package lj.netty;

import cn.hutool.log.StaticLog;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import lj.netty.bean.LJNettyHttpContext;
import lj.netty.channel.ChannelHandlerHttp;
import ntd.util.UtilCatch;

/**
 * @author: liuwenju
 * @date: 2023/6/20 16:59
 * @version: 1.0
 */
public abstract class ComNettyHttp extends ComAbsNettyTcp implements ComNetty {

    //是一个启动NIO服务的辅助启动类
    ServerBootstrap serverBootstrap = new ServerBootstrap();

    public ComNettyHttp(int port) {
        this.port = port;
    }

    /**
     * 启动监听
     */
    public void start() {
        ComNettyHttp comNettyHttp = this;
        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)  // 这里告诉Channel如何接收新的连接
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new HttpServerCodec());
                        // http 消息聚合器 512*1024为接收的最大contentlength
                        pipeline.addLast("httpAggregator",new HttpObjectAggregator(512*1024));
                        pipeline.addLast(new ChannelHandlerHttp() {
                            @Override
                            public String onMsg(LJNettyHttpContext ljNettyHttpContext) {
                                return comNettyHttp.onMsg(ljNettyHttpContext);
                            }
                        });
                    }
                });
        serverBootstrap.option(ChannelOption.SO_BACKLOG, 128);
        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);

        UtilCatch.tryCatchNoRes(() -> {
            ChannelFuture sync = serverBootstrap.bind(port).sync();// 绑定端口，开始接收进来的连接
            StaticLog.info("HTTP服务端[{}]启动成功", port);
            sync.channel().closeFuture().sync();
            StaticLog.info("HTTP服务端[{}]关闭成功", port);
        });
    }

    public abstract String onMsg(LJNettyHttpContext ljNettyHttpContext);

    @Override
    public boolean conn() {
        StaticLog.info("服务端无需重连...");
        return true;
    }

    public static void main(String[] args) {
        new ComNettyHttp(32323) {
            @Override
            public String onMsg(LJNettyHttpContext ljNettyHttpContext) {
                StaticLog.info(ljNettyHttpContext.getRequest().uri());
                return "success";
            }
        }.start();
    }
}
